package org.database.JobListenner;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.database.quartz.TaskLog;
import org.database.quartz.TaskScheduled;
import org.dynamic.config.Application;
import org.dynamic.mail.common.MailCfg;
import org.dynamic.mail.entity.MailMsg;
import org.dynamic.mail.enums.MailMsgType;
import org.dynamic.mail.service.MailService;
import org.dynamic.mail.service.impl.ApacheMailServiceImpl;
import org.dynamic.util.DateConvertUtil;
import org.dynamic.util.SpringContextUtil;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

/**
 * 任务监听器
 *
 * @author huyj
 * @Created 2017-03-23 11:20
 */
public class MyJobListener implements org.quartz.JobListener {
    private Logger logger = LoggerFactory.getLogger(getClass());
    // 线程池
    private static ExecutorService executorService = Executors.newCachedThreadPool();

    public String getName() {
        return "MyJobListener";
    }

    /**
     * (1)
     * 任务执行之前执行
     * Called by the Scheduler when a JobDetail is about to be executed (an associated Trigger has occurred).
     */
    @Override
    public void jobToBeExecuted(final JobExecutionContext context) {
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        TaskScheduled taskScheduled = (TaskScheduled) jobDataMap.get(Application.QUARTZ_DATA);

        if (logger.isInfoEnabled()) {
            logger.info("jobToBeExecuted --> 任务执行之前执行：{}.{}", taskScheduled.getTaskTarget(), taskScheduled.getTaskMethod());
        }

        TaskLog log = (TaskLog) jobDataMap.get(Application.QUARTZ_LOG);
        try {
            log.setTask_status(context.getScheduler().getTriggerState(TriggerKey.triggerKey(taskScheduled.getTaskName(), taskScheduled.getTaskGroup())).name());
        } catch (SchedulerException e) {
            e.printStackTrace();
            logger.error("SchedulerException",e.getMessage());
        }
        log.setLog_type("job");
        log.setExecute_starttime(new Date());
        log.setTask_desc("jobToBeExecuted 任务执行之前执行");
        context.getJobDetail().getJobDataMap().put(Application.QUARTZ_LOG, log);

        //记录日志
        //saveLog(log);
    }

    /**
     * (2)
     * 这个方法正常情况下不执行,但是如果当TriggerListener中的vetoJobExecution方法返回true时,那么执行这个方法.
     * 需要注意的是 如果方法(2)执行 那么(1),(3)这个俩个方法不会执行,因为任务被终止了嘛.
     * Called by the Scheduler when a JobDetail was about to be executed (an associated Trigger has occurred),
     * but a TriggerListener vetoed it's execution.
     */
    @Override
    public void jobExecutionVetoed(JobExecutionContext context) {
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        TaskScheduled taskScheduled = (TaskScheduled) jobDataMap.get(Application.QUARTZ_DATA);
        if (logger.isInfoEnabled()) {
            logger.info("jobExecutionVetoed -->定时任务vetoJobExecution：{}.{}    group[{}]   name[{}]", taskScheduled.getTaskTarget(), taskScheduled.getTaskMethod(), taskScheduled.getTaskGroup(), taskScheduled.getTaskName());
        }
        /*TaskLog log = (TaskLog) jobDataMap.get(Application.QUARTZ_LOG);
        try {
            log.setTask_status(context.getScheduler().getTriggerState(TriggerKey.triggerKey(taskScheduled.getTaskName(), taskScheduled.getTaskGroup())).name());
        } catch (SchedulerException e) {
            e.printStackTrace();
            logger.error("SchedulerException",e.getMessage());
        }
        log.setLog_type("job");
        log.setExecute_starttime(new Date());
        log.setTask_desc("jobExecutionVetoed TriggerListener中的vetoJobExecution方法返回true时执行");
        context.getJobDetail().getJobDataMap().put(Application.QUARTZ_LOG, log);

        //记录日志
        saveLog(log);*/
    }

    /**
     * (3)
     * 任务执行完成后执行,jobException如果它不为空则说明任务在执行过程中出现了异常
     * Called by the Scheduler after a JobDetail has been executed, and be for the associated Trigger's triggered(xx) method has been called.
     */
    @Override
    public void jobWasExecuted(final JobExecutionContext context, JobExecutionException exp) {
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        TaskScheduled taskScheduled = (TaskScheduled) jobDataMap.get(Application.QUARTZ_DATA);
        if (logger.isInfoEnabled()) {
            logger.info("jobWasExecuted --> 定时任务执行结束：{}.{}    group[{}]   name[{}]", taskScheduled.getTaskTarget(), taskScheduled.getTaskMethod(), taskScheduled.getTaskGroup(), taskScheduled.getTaskName());
        }

        TaskLog log = (TaskLog) jobDataMap.get(Application.QUARTZ_LOG);
        try {
            log.setTask_status(context.getScheduler().getTriggerState(TriggerKey.triggerKey(taskScheduled.getTaskName(), taskScheduled.getTaskGroup())).name());
        } catch (SchedulerException e) {
            e.printStackTrace();
            logger.error("SchedulerException",e.getMessage());
        }
        //log.setExecute_starttime(new Date());
        log.setLog_type("job");
        log.setTask_desc("jobWasExecuted 任务执行完成");
        log.setExecute_endtime(new Date());
        log.setTask_periodtime("任务执行时间 " + DateConvertUtil.getDistanceTime(log.getExecute_starttime(), log.getExecute_endtime()));

        if (exp != null) {//任务执行出错  发送邮件
            String info = "任务taskGroup[" + taskScheduled.getTaskGroup() + "] , taskName[" + taskScheduled.getTaskName() + "] ,  任务描述[" + taskScheduled.getTaskDesc() + "]   于 "+ DateConvertUtil.generateDateTime(new Date(),DateConvertUtil.DATE_TIME_FORMAT)+" 执行失败 ,\n 失败原因: " + exp.getMessage();
            log.setTask_desc("jobWasExecuted "+ info);
            sendEmail(info);
        }
        context.getJobDetail().getJobDataMap().put(Application.QUARTZ_LOG, log);

        //记录日志
        saveLog(log);
       // sendEmail("taskGroup[" + taskScheduled.getTaskGroup() + "] , taskName[" + taskScheduled.getTaskName() + "] ,  任务描述[" + taskScheduled.getTaskDesc() + "]   执行完成!");
    }

    private void sendEmail(final String content) {
        executorService.submit(new Runnable() {
            public void run() {
                MailService mailService = new ApacheMailServiceImpl();
                MailMsg msg = new MailMsg();
                msg.setType(MailMsgType.text);
                msg.setSubject("NC新系统定时任务消息");
                msg.setContent(content);
                mailService.sendMail(MailCfg.DEFAULT_TO_NAME, msg);
                //mailService.sendMail("huyj@corp.hxqc.com",msg );
            }
        });
    }


    private void saveLogThread(final TaskLog log) {
        executorService.submit(new Runnable() {
            public void run() {
                ApplicationContext app = SpringContextUtil.getApplicationContext();
               // TaskLogService taskLogService = (TaskLogService) app.getBean("taskLogService");
             //  taskLogService.saveLog(log);
                log.setExecute_endtime(null);
                log.setTask_periodtime(null);
                log.setTask_desc(null);
            }
        });
    }
    private void saveLog(final TaskLog log) {
        ApplicationContext app = SpringContextUtil.getApplicationContext();
       // TaskLogService taskLogService = (TaskLogService) app.getBean("taskLogService");
       // taskLogService.saveLog(log);
        log.setExecute_endtime(null);
        log.setTask_periodtime(null);
        log.setTask_desc(null);
    }


}
